#include "stdafx.h"
#include "Sphere.h"

namespace PhotonMapping
{


Sphere::Sphere(const Math::Vector3 p_Center, float p_Radius, intx p_MaterialId) : IObject(p_MaterialId)
{
	m_Sphere.m_Center = p_Center;
	m_Sphere.m_Radius = p_Radius;
}

// code from http://www.devmaster.net/wiki/Ray-sphere_intersection
// Ray.m_Dir must be normalized!
intx Sphere::TestIntersection(const Math::Ray& p_Ray, float &p_Distance)
{
	using namespace Math;

	Vector3 dst = p_Ray.m_Position - m_Sphere.m_Center;
	float B = -(dst * p_Ray.m_Direction);
	float C = (dst * dst) - (m_Sphere.m_Radius * m_Sphere.m_Radius);
	float D = (B * B) - C;
	if(D > 0)
	{
		D = Sqrt(D);
		const float t0 = B - D;
		const float t1 = B + D;
		if(t1 > 0.0f)
		{
			if(t0 < 0.0f)
			{
				if(t1 < p_Distance)
				{
					p_Distance = t1;
					return IObject::INPRIM;
				}
			}
			else
			{
				if(t0 < p_Distance)
				{
					p_Distance = t0;
					return IObject::HIT;
				}
			}
		}
	}
	return IObject::MISS;
}

const Math::Sphere& Sphere::GetBoundingSphere() const
{
	return m_Sphere;
}

const Math::Vector3 Sphere::GetNormalAt(const Math::Vector3& p_Pos)
{
	Math::Vector3 normal(p_Pos - m_Sphere.m_Center);
	normal.Normalize();
	return normal;
}

}
